﻿#include "TcpDataPreprocessor.h"

const QByteArray TcpDataPreprocessor::fakeFlag=QByteArray(1,(uchar)0xf1);
const QByteArray TcpDataPreprocessor::trueFlag=QByteArray(1,(uchar)0xf2);
const QByteArray TcpDataPreprocessor::beginFlag=QByteArray(1,(uchar)0xf0);
const int TcpDataPreprocessor::headLen=sizeof (dataLen)+trueFlag.size()+beginFlag.size();

TcpDataPreprocessor::TcpDataPreprocessor():QObject()
{
  qRegisterMetaType<TcpDataPreprocessor::PrivateSignalClass>("TcpDataPreprocessor::PrivateSignalClass");
}

TcpDataPreprocessor::~TcpDataPreprocessor()
{}

QByteArray *TcpDataPreprocessor::code(QByteArray *data)
{
  return addHead(addFakeFlag(data));
}

void TcpDataPreprocessor::decode(QByteArray data)
{
  if(trueFlag[0]==lastChar&&beginFlag[0]==data[0])//若上一个报文的结束字节是真头部标志且当前报文的第一个字节是开始标志
    {
      decode1();//直接解析之前的数据
      init();//初始化解析
      dataBuffer.append(lastChar).append(data);//添加当前数据包到数据缓冲区
    }
  else//正常开始解析报文
    {
      int begin=data.indexOf(trueFlag+beginFlag);//查看新到的数据中是否存在头部
      if(-1==begin)//查询结果为-1代表没有找到头部，当前报文可能是是数据体
        {
          if(!dataBuffer.isEmpty())//若数据缓冲区不为空则代表已经开始解析了
            {
              dataBuffer.append(data);//添加新数据到数据缓冲区
            }
          else//数据缓冲区为空代表尚未开始解析头部
            {
              //可能是数据碎片，不做处理
            }
        }
      else//查询结果不为零代表找到了数据包头部
        {
          dataBuffer.append(data.mid(0,begin));//将头部前的数据存入缓冲区
          decode1();//直接解析之前的数据
          init();//初始化解析
          dataBuffer.append(data.mid(begin));//将头部后的数据全部存入缓冲区
        }
    }
  decode1();//尝试解析报文
  lastChar=data[data.size()-1];//将当前报文的最后一个字节记录在lastChar
}

void TcpDataPreprocessor::decode1()
{
  while (!dataBuffer.isEmpty())//数据缓冲区不为空则解析
    {
      if(0>=dataLen)//接收数据头
        {
          if(dataBuffer.size()>=headLen)
            {
              decodeHead();
            }
          else
            {
              return;
            }
        }
      else//接收数据体
        {
          if(dataBuffer.size()>=(dataLen+headLen))// 数据体接收完毕
            {
              decodeBody();
              init();//初始化解析
            }
          return;
        }
    }
}

void TcpDataPreprocessor::decodeHead()
{
  dataLen=*((int*)(dataBuffer.data()+trueFlag.size()+beginFlag.size()));//得出数据包头部加载荷的长度
}

void TcpDataPreprocessor::decodeBody()
{
  QByteArray data=dataBuffer.mid(headLen,dataLen);
  emit signal_decoded(*removeFakeFlag(&data));
}

void TcpDataPreprocessor::init()
{
  dataBuffer.clear();//清空缓冲区
  dataLen=0;//数据长度置零，代表未开始解析
}

QByteArray* TcpDataPreprocessor::addFakeFlag(QByteArray *data)
{
  data->replace(beginFlag,fakeFlag+beginFlag);
  return data;
}

QByteArray* TcpDataPreprocessor::removeFakeFlag(QByteArray *data)
{
  data->replace(fakeFlag+beginFlag,beginFlag);
  return data;
}

QByteArray* TcpDataPreprocessor::addHead(QByteArray *data)
{
  int len=data->size();
  data->prepend((char*)&len,4);
  data->prepend(trueFlag+beginFlag);
  return data;
}
